package com.smartcity.utils;

import com.smartcity.result.ResultBase;
import jakarta.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;


import java.util.List;

@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 参数校验异常，pom文件需引入 spring-boot-starter-validation 依赖
     */
    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseBody
    public ResultBase error(Exception e) {
        log.error("参数校验异常:{}", e.getMessage());
        return ResultBase.error(e.getMessage());
    }

    /**
     * 参数校验异常，pom文件需引入 spring-boot-starter-validation 依赖
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public ResultBase  error(MethodArgumentNotValidException e) {
        // 获取异常体
        BindingResult bindingResult = e.getBindingResult();
        // 从异常体中获取所有异常列表
        List<FieldError> errors = bindingResult.getFieldErrors();
        // 要返回的字符串,拼接的是参数名称以及对应的报错提示
        StringBuilder messageBuilder = new StringBuilder();
        String message = null;
        for (FieldError error : errors) {
            // 报错的参数
            String field = error.getField();
            // 报错的信息
            message = error.getDefaultMessage();
            // 拼接参数名称以及对应的报错提示
            messageBuilder.append(field).append("\t").append(message).append("\n");
        }
        log.error("参数校验异常详情:{}", messageBuilder);
        return ResultBase.error(message);
    }

    /**
     * 自定义异常
     */
    @ExceptionHandler(BizException.class)
    @ResponseBody
    public ResultBase error(BizException e) {
        log.error("自定义异常:{}", e.getMessage());
        return ResultBase.error(e.getMessage());
    }

    /**
     * 空指针异常
     */
    @ExceptionHandler(NullPointerException.class)
    @ResponseBody
    public ResultBase error(NullPointerException e) {
        log.error("空指针异常:{}", e.getMessage());
        return ResultBase.error("空指针异常");
    }

    /**
     * 拦截运行时异常
     */
    @ExceptionHandler(value = RuntimeException.class)
    @ResponseBody
    public ResultBase runtimeExceptionHandle(RuntimeException e) {
        log.error("捕捉到运行时异常:{}", e.getMessage());
        return ResultBase.error("系统运行中异常");
    }

    /**
     * 兜底异常，捕获系统级异常
     */
    @ExceptionHandler(value = Throwable.class)
    @ResponseBody
    public ResultBase throwableHandle(Throwable throwable) {
        log.error("捕获系统级异常:{}", throwable.getMessage());
        return ResultBase.error("系统程序异常");
    }

}
